<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>微信小程序开发指南 - 技术小馆</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #333;
            line-height: 1.6;
        }
        .hero {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
        }
        .card-hover:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .code-block {
            background-color: #2d3748;
            border-left: 4px solid #4a5568;
        }
        .first-letter {
            font-size: 3.5em;
            line-height: 0.8;
            float: left;
            margin-right: 0.2em;
            margin-bottom: -0.2em;
            color: #4a5568;
        }
        .section-divider {
            height: 1px;
            background: linear-gradient(90deg, rgba(200,200,200,0) 0%, rgba(200,200,200,0.5) 50%, rgba(200,200,200,0) 100%);
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <section class="hero text-white py-20 px-4 md:py-32">
        <div class="container mx-auto max-w-6xl">
            <div class="flex flex-col items-center text-center">
                <h1 class="text-4xl md:text-6xl font-bold mb-4">微信小程序开发指南</h1>
                <p class="text-xl md:text-2xl max-w-2xl mb-8">从零开始掌握小程序开发的核心技术与最佳实践</p>
                <div class="flex space-x-4">
                    <a href="#getting-started" class="px-6 py-3 bg-white text-indigo-700 font-semibold rounded-full hover:bg-gray-100 transition duration-300">
                        <i class="fas fa-rocket mr-2"></i>快速开始
                    </a>
                    <a href="#core-concepts" class="px-6 py-3 border-2 border-white text-white font-semibold rounded-full hover:bg-white hover:text-indigo-700 transition duration-300">
                        <i class="fas fa-book mr-2"></i>核心概念
                    </a>
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="container mx-auto max-w-6xl px-4 py-12">
        <!-- Getting Started Section -->
        <section id="getting-started" class="mb-16">
            <div class="flex items-center mb-8">
                <div class="w-12 h-12 bg-indigo-100 rounded-full flex items-center justify-center mr-4">
                    <i class="fas fa-play text-indigo-600 text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">快速开始</h2>
            </div>
            
            <div class="bg-white rounded-xl shadow-md overflow-hidden mb-8 card-hover transition duration-300">
                <div class="p-6">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-800">初始化小程序</h3>
                    <p class="text-gray-600 mb-4">在小程序的入口文件 <code class="bg-gray-100 px-2 py-1 rounded">app.js</code> 中初始化应用：</p>
                    <div class="code-block rounded-lg p-4 mb-4 text-gray-200 font-mono text-sm">
                        <pre><code>// app.js
App({
  onLaunch() {
    // 小程序初始化完成时触发
    console.log('小程序启动了');
  },
  onShow() {
    // 小程序显示时触发
    console.log('小程序显示到了屏幕上');
  },
  onHide() {
    // 小程序隐藏时触发
    console.log('小程序隐藏了');
  }
})</code></pre>
                    </div>
                    <p class="text-gray-600">在小程序的页面文件中，也需要进行类似的初始化：</p>
                    <div class="code-block rounded-lg p-4 mt-4 text-gray-200 font-mono text-sm">
                        <pre><code>// pages/index/index.js
Page({
  data: {
    message: 'Hello World'
  },
  onLoad() {
    console.log('页面加载完成');
  }
})</code></pre>
                    </div>
                </div>
            </div>
            
            <div class="grid md:grid-cols-2 gap-6">
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover transition duration-300">
                    <div class="p-6">
                        <h3 class="text-xl font-semibold mb-3 text-gray-800">小程序代码结构</h3>
                        <p class="text-gray-600 mb-4">小程序由以下文件和目录组成：</p>
                        <ul class="list-disc pl-5 space-y-2">
                            <li><code class="bg-gray-100 px-1 py-0.5 rounded">app.js</code> - 小程序逻辑</li>
                            <li><code class="bg-gray-100 px-1 py-0.5 rounded">app.json</code> - 小程序公共配置</li>
                            <li><code class="bg-gray-100 px-1 py-0.5 rounded">app.wxss</code> - 小程序公共样式表</li>
                            <li><code class="bg-gray-100 px-1 py-0.5 rounded">pages/</code> - 页面目录</li>
                            <li><code class="bg-gray-100 px-1 py-0.5 rounded">utils/</code> - 工具目录</li>
                        </ul>
                    </div>
                </div>
                
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover transition duration-300">
                    <div class="p-6">
                        <h3 class="text-xl font-semibold mb-3 text-gray-800">创建自定义页面</h3>
                        <p class="text-gray-600 mb-4">每个页面由4个文件组成：</p>
                        <ul class="list-disc pl-5 space-y-2">
                            <li><code class="bg-gray-100 px-1 py-0.5 rounded">.js</code> - 页面逻辑</li>
                            <li><code class="bg-gray-100 px-1 py-0.5 rounded">.json</code> - 页面配置</li>
                            <li><code class="bg-gray-100 px-1 py-0.5 rounded">.wxml</code> - 页面结构</li>
                            <li><code class="bg-gray-100 px-1 py-0.5 rounded">.wxss</code> - 页面样式</li>
                        </ul>
                        <div class="mt-4">
                            <img src="https://cdn.nlark.com/yuque/0/2025/png/21449790/1741349837195-80f97770-b544-4493-8988-c3e574031b31.png" alt="页面文件结构" class="rounded-lg border border-gray-200">
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Core Concepts Section -->
        <section id="core-concepts" class="mb-16">
            <div class="flex items-center mb-8">
                <div class="w-12 h-12 bg-indigo-100 rounded-full flex items-center justify-center mr-4">
                    <i class="fas fa-cubes text-indigo-600 text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">核心概念</h2>
            </div>

            <!-- Data Binding -->
            <div class="bg-white rounded-xl shadow-md overflow-hidden mb-8 card-hover transition duration-300">
                <div class="p-6">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-800">数据绑定</h3>
                    <p class="text-gray-600 mb-4">小程序使用 <code class="bg-gray-100 px-2 py-1 rounded">{{}}</code> 语法进行数据绑定：</p>
                    <div class="grid md:grid-cols-2 gap-6">
                        <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm">
                            <div class="mb-2 text-gray-400">// WXML</div>
                            <pre><code>&lt;view&gt;
  &lt;text&gt;{{message}}&lt;/text&gt;
  &lt;text&gt;{{array[0].msg}}&lt;/text&gt;
  &lt;text&gt;{{sex==1?'男':'女'}}&lt;/text&gt;
  &lt;input value="{{message}}"/&gt;
&lt;/view&gt;</code></pre>
                        </div>
                        <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm">
                            <div class="mb-2 text-gray-400">// JS</div>
                            <pre><code>Page({
  data: {
    message: "数据绑定",
    array: [{msg: '1'}, {msg: '2'}],
    sex: 0
  }
})</code></pre>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Conditional Rendering -->
            <div class="bg-white rounded-xl shadow-md overflow-hidden mb-8 card-hover transition duration-300">
                <div class="p-6">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-800">条件渲染</h3>
                    <p class="text-gray-600 mb-4">使用 <code class="bg-gray-100 px-2 py-1 rounded">wx:if</code> 和 <code class="bg-gray-100 px-2 py-1 rounded">hidden</code> 进行条件渲染：</p>
                    <div class="grid md:grid-cols-2 gap-6">
                        <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm">
                            <div class="mb-2 text-gray-400">// 条件判断</div>
                            <pre><code>&lt;view wx:if="{{length &lt; 5}}"&gt;1&lt;/view&gt;
&lt;view wx:elif="{{length &lt; 10}}"&gt;2&lt;/view&gt;
&lt;view wx:else&gt;3&lt;/view&gt;

&lt;block wx:if="{{flag}}"&gt;
  &lt;view&gt;view1&lt;/view&gt;
  &lt;view&gt;view2&lt;/view&gt;
&lt;/block&gt;

&lt;view hidden="{{flag}}"&gt;隐藏内容&lt;/view&gt;</code></pre>
                        </div>
                        <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm">
                            <div class="mb-2 text-gray-400">// JS</div>
                            <pre><code>Page({
  data: {
    length: 7,
    flag: false
  },
  onLoad() {
    setTimeout(() => {
      this.setData({flag: true});
    }, 2000);
  }
})</code></pre>
                        </div>
                    </div>
                    <div class="mt-4 p-4 bg-indigo-50 rounded-lg">
                        <h4 class="font-semibold text-indigo-700 mb-2 flex items-center">
                            <i class="fas fa-lightbulb mr-2"></i>最佳实践
                        </h4>
                        <p class="text-gray-700"><code class="bg-indigo-100 px-1 py-0.5 rounded">wx:if</code> 有更高的切换消耗而 <code class="bg-indigo-100 px-1 py-0.5 rounded">hidden</code> 有更高的初始渲染消耗。频繁切换用 <code class="bg-indigo-100 px-1 py-0.5 rounded">hidden</code>，运行时条件不变用 <code class="bg-indigo-100 px-1 py-0.5 rounded">wx:if</code>。</p>
                    </div>
                </div>
            </div>

            <!-- List Rendering -->
            <div class="bg-white rounded-xl shadow-md overflow-hidden mb-8 card-hover transition duration-300">
                <div class="p-6">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-800">列表渲染</h3>
                    <p class="text-gray-600 mb-4">使用 <code class="bg-gray-100 px-2 py-1 rounded">wx:for</code> 进行列表渲染，默认当前项变量名为 <code class="bg-gray-100 px-2 py-1 rounded">item</code>，下标变量名为 <code class="bg-gray-100 px-2 py-1 rounded">index</code>：</p>
                    <div class="grid md:grid-cols-2 gap-6">
                        <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm">
                            <div class="mb-2 text-gray-400">// WXML</div>
                            <pre><code>&lt;view wx:for="{{users}}" wx:key="id"&gt;
  &lt;text&gt;{{index}}: {{item.name}}&lt;/text&gt;
&lt;/view&gt;

&lt;button bindtap="addRow"&gt;添加一行&lt;/button&gt;</code></pre>
                        </div>
                        <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm">
                            <div class="mb-2 text-gray-400">// JS</div>
                            <pre><code>Page({
  data: {
    users: [
      {id:1, name:'张三', age:20},
      {id:2, name:'李四', age:22},
      {id:3, name:'王五', age:24}
    ]
  },
  addRow() {
    const newUser = {
      id: this.data.users.length + 1,
      name: `用户${this.data.users.length + 1}`,
      age: Math.floor(Math.random() * 10) + 20
    };
    this.setData({
      users: [...this.data.users, newUser]
    });
  }
})</code></pre>
                        </div>
                    </div>
                    <div class="mt-4 p-4 bg-indigo-50 rounded-lg">
                        <h4 class="font-semibold text-indigo-700 mb-2 flex items-center">
                            <i class="fas fa-lightbulb mr-2"></i>关于wx:key
                        </h4>
                        <p class="text-gray-700">使用 <code class="bg-indigo-100 px-1 py-0.5 rounded">wx:key</code> 可以提高列表渲染性能并维持组件状态，特别是在列表项会动态改变时。</p>
                    </div>
                </div>
            </div>

            <!-- Event Handling -->
            <div class="bg-white rounded-xl shadow-md overflow-hidden mb-8 card-hover transition duration-300">
                <div class="p-6">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-800">事件处理</h3>
                    <p class="text-gray-600 mb-4">小程序使用 <code class="bg-gray-100 px-2 py-1 rounded">bind</code> 和 <code class="bg-gray-100 px-2 py-1 rounded">catch</code> 前缀绑定事件：</p>
                    <div class="grid md:grid-cols-2 gap-6">
                        <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm">
                            <div class="mb-2 text-gray-400">// WXML</div>
                            <pre><code>&lt;button bindtap="handleTap" data-id="123"&gt;
  点击我
&lt;/button&gt;

&lt;view bindtap="parentTap"&gt;
  &lt;button catchtap="childTap"&gt;
    不会冒泡
  &lt;/button&gt;
&lt;/view&gt;</code></pre>
                        </div>
                        <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm">
                            <div class="mb-2 text-gray-400">// JS</div>
                            <pre><code>Page({
  handleTap(e) {
    console.log('点击事件', e);
    const id = e.currentTarget.dataset.id;
    console.log('获取data-id:', id);
  },
  parentTap() {
    console.log('父元素点击');
  },
  childTap() {
    console.log('子元素点击 - 不会冒泡');
  }
})</code></pre>
                        </div>
                    </div>
                    <div class="mt-4 p-4 bg-indigo-50 rounded-lg">
                        <h4 class="font-semibold text-indigo-700 mb-2 flex items-center">
                            <i class="fas fa-lightbulb mr-2"></i>事件区别
                        </h4>
                        <p class="text-gray-700"><code class="bg-indigo-100 px-1 py-0.5 rounded">bind</code> 绑定的事件会冒泡，<code class="bg-indigo-100 px-1 py-0.5 rounded">catch</code> 绑定的事件不会冒泡。</p>
                    </div>
                </div>
            </div>

            <!-- Lifecycle -->
            <div class="bg-white rounded-xl shadow-md overflow-hidden mb-8 card-hover transition duration-300">
                <div class="p-6">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-800">生命周期</h3>
                    <p class="text-gray-600 mb-4">小程序和页面都有各自的生命周期函数：</p>
                    <div class="grid md:grid-cols-2 gap-6">
                        <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm">
                            <div class="mb-2 text-gray-400">// 应用生命周期</div>
                            <pre><code>App({
  onLaunch() {
    // 初始化完成
  },
  onShow() {
    // 显示
  },
  onHide() {
    // 隐藏
  },
  onError() {
    // 错误
  }
})</code></pre>
                        </div>
                        <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm">
                            <div class="mb-2 text-gray-400">// 页面生命周期</div>
                            <pre><code>Page({
  onLoad() {
    // 页面加载
  },
  onShow() {
    // 页面显示
  },
  onReady() {
    // 页面初次渲染完成
  },
  onHide() {
    // 页面隐藏
  },
  onUnload() {
    // 页面卸载
  }
})</code></pre>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Data Flow Chart -->
        <section class="mb-16">
            <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover transition duration-300">
                <div class="p-6">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-800">小程序数据流</h3>
                    <div class="mermaid">
                        graph LR
                            A[逻辑层] -->|setData| B[视图层]
                            B -->|事件| A
                            A -->|API调用| C[原生能力]
                            C -->|回调| A
                    </div>
                    <div class="mt-4 p-4 bg-indigo-50 rounded-lg">
                        <h4 class="font-semibold text-indigo-700 mb-2 flex items-center">
                            <i class="fas fa-project-diagram mr-2"></i>数据流说明
                        </h4>
                        <p class="text-gray-700">小程序采用 <code class="bg-indigo-100 px-1 py-0.5 rounded">逻辑层</code> 和 <code class="bg-indigo-100 px-1 py-0.5 rounded">视图层</code> 分离的架构，通过 <code class="bg-indigo-100 px-1 py-0.5 rounded">setData</code> 实现数据绑定和单向数据流。</p>
                    </div>
                </div>
            </div>
        </section>

        <!-- FAQ Section -->
        <section class="mb-16">
            <div class="flex items-center mb-8">
                <div class="w-12 h-12 bg-indigo-100 rounded-full flex items-center justify-center mr-4">
                    <i class="fas fa-question-circle text-indigo-600 text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">常见问题</h2>
            </div>
            
            <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover transition duration-300">
                <div class="p-6">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">页面不加载问题</h3>
                    <p class="text-gray-600 mb-4">如果页面没有正确加载，请检查：</p>
                    <div class="code-block rounded-lg p-4 text-gray-200 font-mono text-sm">
                        <pre><code>// 确保在页面JS文件中正确初始化
Page({})</code></pre>
                    </div>
                </div>
            </div>
        </section>
    </main>

    <!-- Footer -->
    <footer class="bg-gray-900 text-gray-300 py-8">
        <div class="container mx-auto max-w-6xl px-4">
            <div class="flex flex-col md:flex-row justify-between items-center">
                <div class="mb-4 md:mb-0">
                    <h3 class="text-xl font-semibold text-white mb-2">技术小馆</h3>
                    <a href="http://www.yuque.com/jtostring" class="text-indigo-300 hover:text-white transition duration-300">
                        <i class="fas fa-external-link-alt mr-1"></i> http://www.yuque.com/jtostring
                    </a>
                </div>
                <div class="flex space-x-4">
                    <a href="#" class="w-10 h-10 rounded-full bg-gray-800 flex items-center justify-center hover:bg-indigo-600 transition duration-300">
                        <i class="fab fa-github"></i>
                    </a>
                    <a href="#" class="w-10 h-10 rounded-full bg-gray-800 flex items-center justify-center hover:bg-blue-500 transition duration-300">
                        <i class="fab fa-twitter"></i>
                    </a>
                    <a href="#" class="w-10 h-10 rounded-full bg-gray-800 flex items-center justify-center hover:bg-red-500 transition duration-300">
                        <i class="fab fa-youtube"></i>
                    </a>
                </div>
            </div>
        </div>
    </footer>

    <!-- Mermaid.js for diagrams -->
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>